package com.cloud.admin.adapter;

import com.cloud.admin.adapter.dto.AgentDTO;
import com.cloud.admin.adapter.dto.InstanceDTO;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class ConsulAdapter {
    private static final String[] EMPTY = new String[0];

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/v1/agent/self")
    public AgentDTO getAgent() {
        AgentDTO agentDTO = new AgentDTO();
        agentDTO.setConfig(new AgentDTO.ConfigDTO());
        return agentDTO;
    }

    @GetMapping("/v1/catalog/services")
    public ResponseEntity<Map> getServices() {
        List<String> services = discoveryClient.getServices();
        Map serviceMaps = new HashMap<>();
        for (String service : services) {
            serviceMaps.put(service, EMPTY);
        }
        return createResponseEntity(serviceMaps);
    }

    @GetMapping("/v1/health/service/{serviceId}")
    public ResponseEntity<List<InstanceDTO>> getService(@PathVariable("serviceId") String serviceId) {
        List<InstanceDTO> instanceList = new ArrayList<>();
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
        if (CollectionUtils.isNotEmpty(instances)) {
            for (ServiceInstance instance : instances) {
                InstanceDTO.ServiceDTO serviceDTO = new InstanceDTO.ServiceDTO();
                serviceDTO.setId(serviceId);
                serviceDTO.setService(serviceId);
                serviceDTO.setAddress(instance.getHost());
                serviceDTO.setPort(instance.getPort());

                InstanceDTO.ChecksDTO checksDTO = new InstanceDTO.ChecksDTO();
                checksDTO.setServiceID(serviceId);
                checksDTO.setServiceName(serviceId);

                InstanceDTO instanceDTO = new InstanceDTO();
                instanceDTO.setNode(new InstanceDTO.NodeDTO());
                instanceDTO.setService(serviceDTO);
                instanceDTO.setChecks(Lists.newArrayList(checksDTO));
                instanceList.add(instanceDTO);
            }
        }
        return createResponseEntity(instanceList);
    }

    private <T> ResponseEntity<T> createResponseEntity(T body) {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("X-Consul-Index", "" + System.currentTimeMillis());
        return new ResponseEntity<>(body, headers, HttpStatus.OK);
    }
}